nanopyx.liquid._le_interpolation_nearest_neighbor_

  1import numpy as np
  2
  3from .__njit__ import njit, prange
  4
  5
  6def _interpolate(image, row, col, rows, cols):
  7    r = int(row)
  8    c = int(col)
  9    if r < 0 or r >= rows or c < 0 or c >= cols:
 10        return 0
 11    else:
 12        return image[r, c]
 13
 14
 15@njit(cache=True)
 16def _njit_interpolate(image, row, col, rows, cols):
 17    r = int(row)
 18    c = int(col)
 19    if r < 0 or r >= rows or c < 0 or c >= cols:
 20        return 0
 21    else:
 22        return image[r, c]
 23
 24
 25def shift_magnify(
 26    image: np.ndarray,
 27    shift_row: np.ndarray,
 28    shift_col: np.ndarray,
 29    magnification_row: float,
 30    magnification_col: float,
 31) -> np.ndarray:
 32    """
 33    Shift and magnify using nearest neighbor interpolation.
 34    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
 35    :param shift_row: 1D array with size (nFrames) with values to shift the rows
 36    :param shift_col: 1D array with size (nFrames) with values to shift the cols
 37    :param magnification_row: float magnification factor for the rows
 38    :param magnification_col: float magnification factor for the cols
 39    :return: 3D float32 numpy array with the result
 40    """
 41
 42    nFrames = image.shape[0]
 43    rows = image.shape[1]
 44    cols = image.shape[2]
 45    rowsM = int(rows * magnification_row)
 46    colsM = int(cols * magnification_col)
 47
 48    image_out = np.zeros((nFrames, rowsM, colsM), dtype=np.float32)
 49    for f in range(nFrames):
 50        for j in range(colsM):
 51            col = j / magnification_col - shift_col[f]
 52            for i in range(rowsM):
 53                row = i / magnification_row - shift_row[f]
 54                image_out[f, i, j] = _interpolate(image[f, :, :], row, col, rows, cols)
 55
 56    return image_out
 57
 58
 59@njit(cache=True, parallel=True)
 60def njit_shift_magnify(
 61    image: np.ndarray,
 62    shift_row: np.ndarray,
 63    shift_col: np.ndarray,
 64    magnification_row: float,
 65    magnification_col: float,
 66) -> np.ndarray:
 67    """
 68    Shift and magnify using nearest neighbor interpolation.
 69    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
 70    :param shift_row: 1D array with size (nFrames) with values to shift the rows
 71    :param shift_col: 1D array with size (nFrames) with values to shift the cols
 72    :param magnification_row: float magnification factor for the rows
 73    :param magnification_col: float magnification factor for the cols
 74    :return: 3D float32 numpy array with the result
 75    """
 76
 77    nFrames = image.shape[0]
 78    rows = image.shape[1]
 79    cols = image.shape[2]
 80    rowsM = int(rows * magnification_row)
 81    colsM = int(cols * magnification_col)
 82
 83    image_out = np.zeros((nFrames, rowsM, colsM), dtype=np.float32)
 84    for f in range(nFrames):
 85        for j in prange(colsM):
 86            col = j / magnification_col - shift_col[f]
 87            for i in range(rowsM):
 88                row = i / magnification_row - shift_row[f]
 89                image_out[f, i, j] = _njit_interpolate(
 90                    image[f, :, :], row, col, rows, cols
 91                )
 92
 93    return image_out
 94
 95
 96def shift_scale_rotate(
 97    image: np.ndarray,
 98    shift_row: np.ndarray,
 99    shift_col: np.ndarray,
100    scale_row: float,
101    scale_col: float,
102    angle: float,
103) -> np.ndarray:
104    """
105    Shift, magnify and rotate using nearest neighbor interpolation.
106    The order of operations is SCALE AND ROTATE AROUND CENTER THEN SHIFT
107    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
108    :param shift_row: 1D array with size (nFrames) with values to shift the rows
109    :param shift_col: 1D array with size (nFrames) with values to shift the cols
110    :param scale_row: float scale factor for the rows
111    :param scale_col: float scale factor for the cols
112    :param angle: float angle of rotation in radians. positive is counter clockwise
113    :return: 3D float32 numpy array with the result
114    """
115
116    nFrames = image.shape[0]
117    rows = image.shape[1]
118    cols = image.shape[2]
119
120    center_row = rows / 2
121    center_col = cols / 2
122    # center_rowM = (rows * scale_row) / 2
123    # center_colM = (cols * scale_col) / 2
124
125    # Composing an affine transform
126    # Its scale => rotate => shift, but we iterate the final image so shift is the first operation on the vector
127    # SCALE     ROTATE         SHIFT
128    # sx  0 0   +cos -sin 0    0 0 tx   j     col
129    #  0 sy 0 . +sin +cos 0  . 0 0 ty . i  =  row
130    #  0  0 1     0    0  1    0 0  1   1      1
131
132    # After calculations we have
133    # SHIFT . SCALE . ROTATE = a  b  tcol
134    #                          c  d  trow
135    #                          0  0   1
136    # We multiply the matrix by every vector (i,j,1)
137    
138    a = np.cos(angle) / scale_col
139    b = -np.sin(angle)/ scale_col
140    c = np.sin(angle) / scale_row
141    d = np.cos(angle) / scale_row
142    
143    # Note#1:tcol and trow are simply shift_col and shift_row rotated and thus are functions of a,b,c,d
144    #   In the below code we simplify it by separating it by their common factors a,b,c,d
145
146    # Note#2: In reality we have to translate by the center before and after to have centered coordinates
147    # In order to keep the same image size during scaling the translation for centered coordinates is given by 
148    # (center_magnified - center_og) - center_magnified == center_og
149    # This can be seen by noting that when (i,j)=(0,0) we are actually at (center_magnified - center_og) coordinates on the scaled image
150
151    image_out = np.zeros((nFrames, rows, cols), dtype=np.float32)
152    for f in range(nFrames):
153        for j in range(cols):
154            for i in range(rows):
155                col = (
156                    (a * (j - center_col-shift_col[f]) + b * (i - center_row-shift_row[f]))
157                    + center_col
158                )
159                row = (
160                    (c * (j - center_col-shift_col[f]) + d * (i - center_row-shift_row[f]))
161                    + center_row
162                )
163                image_out[f, i, j] = _interpolate(image[f, :, :], row, col, rows, cols)
164
165    return image_out
166
167
168@njit(cache=True, parallel=True)
169def njit_shift_scale_rotate(
170    image: np.ndarray,
171    shift_row: np.ndarray,
172    shift_col: np.ndarray,
173    scale_row: float,
174    scale_col: float,
175    angle: float,
176) -> np.ndarray:
177    """
178    Shift, magnify and rotate using nearest neighbor interpolation.
179    The order of operations is SCALE AND ROTATE AROUND CENTER THEN SHIFT
180    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
181    :param shift_row: 1D array with size (nFrames) with values to shift the rows
182    :param shift_col: 1D array with size (nFrames) with values to shift the cols
183    :param scale_row: float scale factor for the rows
184    :param scale_col: float scale factor for the cols
185    :param angle: float angle of rotation in radians. positive is counter clockwise
186    :return: 3D float32 numpy array with the result
187    """
188
189    nFrames = image.shape[0]
190    rows = image.shape[1]
191    cols = image.shape[2]
192
193    center_row = rows / 2
194    center_col = cols / 2
195
196    # center_rowM = (rows * scale_row) / 2
197    # center_colM = (cols * scale_col) / 2
198
199    a = np.cos(angle) / scale_col
200    b = -np.sin(angle) / scale_col
201    c = np.sin(angle) / scale_row
202    d = np.cos(angle) / scale_row
203
204    image_out = np.zeros((nFrames, rows, cols), dtype=np.float32)
205    for f in range(nFrames):
206        for j in prange(cols):
207            for i in range(rows):
208                col = (
209                    (a * (j - center_col-shift_col[f]) + b * (i - center_row-shift_row[f]))
210                    + center_col
211                )
212                row = (
213                    (c * (j - center_col-shift_col[f]) + d * (i - center_row-shift_row[f]))
214                    + center_row
215                )
216                image_out[f, i, j] = _njit_interpolate(image[f, :, :], row, col, rows, cols)
217
218    return image_out
def shift_magnify( image: numpy.ndarray, shift_row: numpy.ndarray, shift_col: numpy.ndarray, magnification_row: float, magnification_col: float) -> numpy.ndarray:
26def shift_magnify(
27    image: np.ndarray,
28    shift_row: np.ndarray,
29    shift_col: np.ndarray,
30    magnification_row: float,
31    magnification_col: float,
32) -> np.ndarray:
33    """
34    Shift and magnify using nearest neighbor interpolation.
35    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
36    :param shift_row: 1D array with size (nFrames) with values to shift the rows
37    :param shift_col: 1D array with size (nFrames) with values to shift the cols
38    :param magnification_row: float magnification factor for the rows
39    :param magnification_col: float magnification factor for the cols
40    :return: 3D float32 numpy array with the result
41    """
42
43    nFrames = image.shape[0]
44    rows = image.shape[1]
45    cols = image.shape[2]
46    rowsM = int(rows * magnification_row)
47    colsM = int(cols * magnification_col)
48
49    image_out = np.zeros((nFrames, rowsM, colsM), dtype=np.float32)
50    for f in range(nFrames):
51        for j in range(colsM):
52            col = j / magnification_col - shift_col[f]
53            for i in range(rowsM):
54                row = i / magnification_row - shift_row[f]
55                image_out[f, i, j] = _interpolate(image[f, :, :], row, col, rows, cols)
56
57    return image_out

Shift and magnify using nearest neighbor interpolation.

Parameters
  • image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
  • shift_row: 1D array with size (nFrames) with values to shift the rows
  • shift_col: 1D array with size (nFrames) with values to shift the cols
  • magnification_row: float magnification factor for the rows
  • magnification_col: float magnification factor for the cols
Returns

3D float32 numpy array with the result

@njit(cache=True, parallel=True)
def njit_shift_magnify( image: numpy.ndarray, shift_row: numpy.ndarray, shift_col: numpy.ndarray, magnification_row: float, magnification_col: float) -> numpy.ndarray:
60@njit(cache=True, parallel=True)
61def njit_shift_magnify(
62    image: np.ndarray,
63    shift_row: np.ndarray,
64    shift_col: np.ndarray,
65    magnification_row: float,
66    magnification_col: float,
67) -> np.ndarray:
68    """
69    Shift and magnify using nearest neighbor interpolation.
70    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
71    :param shift_row: 1D array with size (nFrames) with values to shift the rows
72    :param shift_col: 1D array with size (nFrames) with values to shift the cols
73    :param magnification_row: float magnification factor for the rows
74    :param magnification_col: float magnification factor for the cols
75    :return: 3D float32 numpy array with the result
76    """
77
78    nFrames = image.shape[0]
79    rows = image.shape[1]
80    cols = image.shape[2]
81    rowsM = int(rows * magnification_row)
82    colsM = int(cols * magnification_col)
83
84    image_out = np.zeros((nFrames, rowsM, colsM), dtype=np.float32)
85    for f in range(nFrames):
86        for j in prange(colsM):
87            col = j / magnification_col - shift_col[f]
88            for i in range(rowsM):
89                row = i / magnification_row - shift_row[f]
90                image_out[f, i, j] = _njit_interpolate(
91                    image[f, :, :], row, col, rows, cols
92                )
93
94    return image_out

Shift and magnify using nearest neighbor interpolation.

Parameters
  • image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
  • shift_row: 1D array with size (nFrames) with values to shift the rows
  • shift_col: 1D array with size (nFrames) with values to shift the cols
  • magnification_row: float magnification factor for the rows
  • magnification_col: float magnification factor for the cols
Returns

3D float32 numpy array with the result

def shift_scale_rotate( image: numpy.ndarray, shift_row: numpy.ndarray, shift_col: numpy.ndarray, scale_row: float, scale_col: float, angle: float) -> numpy.ndarray:
 97def shift_scale_rotate(
 98    image: np.ndarray,
 99    shift_row: np.ndarray,
100    shift_col: np.ndarray,
101    scale_row: float,
102    scale_col: float,
103    angle: float,
104) -> np.ndarray:
105    """
106    Shift, magnify and rotate using nearest neighbor interpolation.
107    The order of operations is SCALE AND ROTATE AROUND CENTER THEN SHIFT
108    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
109    :param shift_row: 1D array with size (nFrames) with values to shift the rows
110    :param shift_col: 1D array with size (nFrames) with values to shift the cols
111    :param scale_row: float scale factor for the rows
112    :param scale_col: float scale factor for the cols
113    :param angle: float angle of rotation in radians. positive is counter clockwise
114    :return: 3D float32 numpy array with the result
115    """
116
117    nFrames = image.shape[0]
118    rows = image.shape[1]
119    cols = image.shape[2]
120
121    center_row = rows / 2
122    center_col = cols / 2
123    # center_rowM = (rows * scale_row) / 2
124    # center_colM = (cols * scale_col) / 2
125
126    # Composing an affine transform
127    # Its scale => rotate => shift, but we iterate the final image so shift is the first operation on the vector
128    # SCALE     ROTATE         SHIFT
129    # sx  0 0   +cos -sin 0    0 0 tx   j     col
130    #  0 sy 0 . +sin +cos 0  . 0 0 ty . i  =  row
131    #  0  0 1     0    0  1    0 0  1   1      1
132
133    # After calculations we have
134    # SHIFT . SCALE . ROTATE = a  b  tcol
135    #                          c  d  trow
136    #                          0  0   1
137    # We multiply the matrix by every vector (i,j,1)
138    
139    a = np.cos(angle) / scale_col
140    b = -np.sin(angle)/ scale_col
141    c = np.sin(angle) / scale_row
142    d = np.cos(angle) / scale_row
143    
144    # Note#1:tcol and trow are simply shift_col and shift_row rotated and thus are functions of a,b,c,d
145    #   In the below code we simplify it by separating it by their common factors a,b,c,d
146
147    # Note#2: In reality we have to translate by the center before and after to have centered coordinates
148    # In order to keep the same image size during scaling the translation for centered coordinates is given by 
149    # (center_magnified - center_og) - center_magnified == center_og
150    # This can be seen by noting that when (i,j)=(0,0) we are actually at (center_magnified - center_og) coordinates on the scaled image
151
152    image_out = np.zeros((nFrames, rows, cols), dtype=np.float32)
153    for f in range(nFrames):
154        for j in range(cols):
155            for i in range(rows):
156                col = (
157                    (a * (j - center_col-shift_col[f]) + b * (i - center_row-shift_row[f]))
158                    + center_col
159                )
160                row = (
161                    (c * (j - center_col-shift_col[f]) + d * (i - center_row-shift_row[f]))
162                    + center_row
163                )
164                image_out[f, i, j] = _interpolate(image[f, :, :], row, col, rows, cols)
165
166    return image_out

Shift, magnify and rotate using nearest neighbor interpolation. The order of operations is SCALE AND ROTATE AROUND CENTER THEN SHIFT

Parameters
  • image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
  • shift_row: 1D array with size (nFrames) with values to shift the rows
  • shift_col: 1D array with size (nFrames) with values to shift the cols
  • scale_row: float scale factor for the rows
  • scale_col: float scale factor for the cols
  • angle: float angle of rotation in radians. positive is counter clockwise
Returns

3D float32 numpy array with the result

@njit(cache=True, parallel=True)
def njit_shift_scale_rotate( image: numpy.ndarray, shift_row: numpy.ndarray, shift_col: numpy.ndarray, scale_row: float, scale_col: float, angle: float) -> numpy.ndarray:
169@njit(cache=True, parallel=True)
170def njit_shift_scale_rotate(
171    image: np.ndarray,
172    shift_row: np.ndarray,
173    shift_col: np.ndarray,
174    scale_row: float,
175    scale_col: float,
176    angle: float,
177) -> np.ndarray:
178    """
179    Shift, magnify and rotate using nearest neighbor interpolation.
180    The order of operations is SCALE AND ROTATE AROUND CENTER THEN SHIFT
181    :param image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
182    :param shift_row: 1D array with size (nFrames) with values to shift the rows
183    :param shift_col: 1D array with size (nFrames) with values to shift the cols
184    :param scale_row: float scale factor for the rows
185    :param scale_col: float scale factor for the cols
186    :param angle: float angle of rotation in radians. positive is counter clockwise
187    :return: 3D float32 numpy array with the result
188    """
189
190    nFrames = image.shape[0]
191    rows = image.shape[1]
192    cols = image.shape[2]
193
194    center_row = rows / 2
195    center_col = cols / 2
196
197    # center_rowM = (rows * scale_row) / 2
198    # center_colM = (cols * scale_col) / 2
199
200    a = np.cos(angle) / scale_col
201    b = -np.sin(angle) / scale_col
202    c = np.sin(angle) / scale_row
203    d = np.cos(angle) / scale_row
204
205    image_out = np.zeros((nFrames, rows, cols), dtype=np.float32)
206    for f in range(nFrames):
207        for j in prange(cols):
208            for i in range(rows):
209                col = (
210                    (a * (j - center_col-shift_col[f]) + b * (i - center_row-shift_row[f]))
211                    + center_col
212                )
213                row = (
214                    (c * (j - center_col-shift_col[f]) + d * (i - center_row-shift_row[f]))
215                    + center_row
216                )
217                image_out[f, i, j] = _njit_interpolate(image[f, :, :], row, col, rows, cols)
218
219    return image_out

Shift, magnify and rotate using nearest neighbor interpolation. The order of operations is SCALE AND ROTATE AROUND CENTER THEN SHIFT

Parameters
  • image: 3D numpy array to interpolate with size (nFrames, nRow, nCol)
  • shift_row: 1D array with size (nFrames) with values to shift the rows
  • shift_col: 1D array with size (nFrames) with values to shift the cols
  • scale_row: float scale factor for the rows
  • scale_col: float scale factor for the cols
  • angle: float angle of rotation in radians. positive is counter clockwise
Returns

3D float32 numpy array with the result